module ysyx_22040213_top(
	input clk,	
	input rst,
	input valid_in,
	output [63:0] dnpc,
//	output [63:0]instt,
	output [63:0]inst,
	output o_reg_valid,
	output reg [63:0] pc,

	//for difftest//
	output o_reg_id_bubble,
	output o_reg_exe_bubble,
	output o_reg_devices_access,
	output [31:0] o_reg_inst,
	output [63:0] o_reg_dnpc
);
/*verilator lint_off UNUSED*/
/*verilator lint_off UNDRIVEN*/
assign inst = o_icache_rdata;
//---------------IF------------//
wire IF_allow_in;
wire IF_to_ID_valid;
wire br_bus_valid;
wire pc_ready_go;
wire IF_ready_go = (o_icache_data_ok || if_inst_valid) ;

wire pc_w_en;
reg IF_valid;

ysyx_22040213_pc pc1(
	.rst(rst),
	.clk(clk),

	.to_fs_valid(to_fs_valid),
	.IF_ready_go(IF_ready_go),
	.ID_allow_in(ID_allow_in),
	
	.IF_to_ID_valid(IF_to_ID_valid),
	.IF_allow_in(IF_allow_in),
	.IF_valid(IF_valid),
	.dnpc(dnpc),

	.pc_w_en(pc_w_en),
	.pc(pc)
);

wire [63:0] pc_link;

ysyx_22040213_pc_add pc_a(
	.pc(pc),
	.pc_link(pc_link)
);
/*
ysyx_22040213_instfetch if1(
	.rst(rst),
	.pc(pc),
	.instt(instt)
);
*/
wire [63:0] inst_axi;
wire if_addr_ok;
wire if_data_ok;
wire o_if_wr;
wire o_if_req;
wire [2:0] o_if_size;
wire [63:0] o_if_addr;
wire [7:0] o_if_wstrb;
wire [63:0] o_if_wdata;
wire [63:0] i_if_rdata;

ysyx_22040213_instfetch_port if3(
	.rst(rst),
	.pc(dnpc),
	.IF_allow_in(IF_allow_in),
	.if_inst(inst_axi),
	.if_addr_ok(if_addr_ok),
	.if_data_ok(if_data_ok),

	.i_if_addr_ok(i_if_addr_ok),
	.i_if_data_ok(i_if_data_ok),
	.i_if_rdata(o_axi_inst_rdata),
	
	.o_if_wr(o_if_wr),
	.o_if_req(o_if_req),
	.o_if_size(o_if_size),
	.o_if_addr(o_if_addr),
	.o_if_wstrb(o_if_wstrb),
	.o_if_wdata(o_if_wdata)
);

wire i_if_addr_ok;
wire i_if_data_ok;

inst_compare com(
	.instt(inst_axi & {64{o_axi_inst_data_ok}}),
	.instt_syn(o_icache_rdata & {64{o_icache_data_ok}})
);
//cache if
wire o_icache_addr_ok;
wire o_icache_data_ok;
wire [63:0] o_icache_rdata;


wire o_icache_rd_req;
wire [2:0] o_icache_rd_type;
wire [63:0] o_icache_rd_addr;
wire o_icache_wr_req;
wire [2:0] o_icache_wr_type;
wire [63:0] o_icache_wr_addr;
wire [7:0] o_icache_wr_wstrb;
wire [63:0] o_icache_wr_data;
wire i_cache_ds;
ysyx_22040213_cache icache(
	.clk(clk),
	.rst(rst),
	
	.i_cache_req(o_if_req),
	.i_cache_wr(1'b0),
	.i_cache_addr(o_if_addr),
	.i_cache_wdata(64'b0),
	.i_cache_wstrb(8'b0),
	.o_cache_addr_ok(o_icache_addr_ok),
	.o_cache_data_ok(o_icache_data_ok),
	.o_cache_rdata(o_icache_rdata),

	.o_cache_rd_req(o_icache_rd_req),
	.o_cache_rd_type(o_icache_rd_type),
	.o_cache_rd_addr(o_icache_rd_addr),
	.i_cache_rd_rdy(i_icache_rd_rdy),

	.i_cache_ret_valid(i_icache_ret_valid),
	.i_cache_ret_last(i_icache_ret_last),
	.i_cache_ret_data(i_icache_ret_data),

	.o_cache_wr_req(o_icache_wr_req),
	.o_cache_wr_type(o_icache_wr_type),
	.o_cache_wr_addr(o_icache_wr_addr),
	.o_cache_wr_wstrb(o_icache_wr_wstrb),
	.o_cache_wr_data(o_icache_wr_data),
	.i_cache_wr_rdy(i_icache_wr_rdy),
	.devices_access(i_cache_ds)
);
//----------END--IF------------//
//------------IF/ID reg--------//
wire [63:0] o_id_pc_link;
wire [63:0] o_id_inst_dram;

wire [63:0] o_id_pc_link;
wire [63:0] o_id_inst_sram;
wire [63:0] o_if_dnpc;
wire [63:0] o_if_pc;

wire o_bub_ID_ready_go;// = 1'b1;

wire ID_allow_in;
wire ID_to_EXE_valid;
wire if_inst_valid;
wire ID_valid;
wire o_id_id_bubble;
wire o_id_diff_clint_trap;

ysyx_22040213_IDReg buf1_IF_ID_REG(
	.clk(clk),
	.rst(rst),
	.flush(id_flush),

	//special inst reg
	.IF_ready_go(IF_ready_go),
	.if_inst_valid(if_inst_valid),
	//end

	.IF_to_ID_valid(IF_to_ID_valid),
	.ID_valid(ID_valid),
	//id ready_go
	.o_bub_ID_ready_go(o_bub_ID_ready_go),//when not exe_bubble and ram data_ok
	.EXE_allow_in(EXE_allow_in),

	.ID_to_EXE_valid(ID_to_EXE_valid),
	.ID_allow_in(ID_allow_in),

	//data in and data out
	.i_id_inst(o_icache_rdata),
	.pc(pc),
	.dnpc(dnpc),
	//.pc_ready_go(to_fs_valid),
	.o_if_dnpc(o_if_dnpc),
	.o_if_pc(o_if_pc),
	.i_id_pc_link(pc_link),
	.o_id_inst_sram(o_id_inst_sram),
	.o_id_pc_link(o_id_pc_link),
	//DIFFTEST
	.i_id_diff_clint_trap(o_clint_trap_go),
	.o_id_diff_clint_trap(o_id_diff_clint_trap)
);


//---------END ID REG----------//
//---------------ID------------//

wire pc_stall;
wire exe_flush;
wire id_flush;
wire id_bubble;
wire exe_bubble;
wire [4:0] rs1;
wire [4:0] rs2;

wire [63:0] src1;
wire [63:0] src2;

wire [63:0] o_bub_src1;
wire [63:0] o_bub_src2;

wire o_clint_trap_go;

ysyx_22040213_bubble bubble1(
	.rs1(rs1),
	.rs2(rs2),
	.o_exe_rd(o_exe_rd),
	.o_mem_rd(o_mem_rd),
	.o_wb_rd(o_wb_rd),
	.AluData1_en(|AluData1_en[2:0]),
	.AluData2_en(|(AluData2_en[0] || |(AluData2_en[6:5]))),
	.i_jump_en(nextpc_en),
	.i_jumpr_en(op_jalr),
	.sm_en(sm_en),
	.o_exe_w_en(o_exe_w_en),
	.o_mem_w_en(o_mem_w_en),
	.o_wb_w_en(o_wb_w_en),
	.ID_allow_in(ID_allow_in),
	.EXE_ready_go(EXE_ready_go),
	.exe_load(o_exe_lm_en),
	.exe_flush(exe_flush),
	.id_flush(id_flush),
	.MEM_to_WB_valid(MEM_to_WB_valid),

	.o_bub_src1(o_bub_src1),
	.o_bub_src2(o_bub_src2),
	.src1(src1),
	.src2(src2),
	.i_exe_adata(adata),
	.i_mem_wdata(wdata),
	.i_wb_wdata(o_wb_wdata),

	.ID_ready_go(o_bub_ID_ready_go),
	.id_bubble(id_bubble),
	.exe_bubble(exe_bubble),
	.pc_stall(pc_stall)
);

wire [4:0] rd;
wire [2:0] funct3;
wire [6:0] funct7;
wire [63:0] ext_imm;
wire [6:0] opcode;
wire [63:0] shamt;

wire [4:0] nextpc_en;
wire [3:0] RegisterWritedata_en;
wire [3:0] AluData1_en;
wire [6:0] AluData2_en;
wire [16:0] alu_op;

wire op_jalr;
wire jumpb_en; //branch_if enable
wire imm_en;
wire pc_en; //data1 sel enable
wire w_en;
wire jumpb; //output
wire lm_en;
wire sm_en;
wire sub_en;//beneath may need to shrink?
wire word_en;
wire rv64m_en;
wire arith_en;
wire lui_en;

wire srai;
wire mret;
wire ecall;
wire csrrs;
wire csrrw;

wire [11:0] csr_rs1;
wire rem;
wire remu;
wire remuw;
wire remw;
wire div;
wire divu;
wire divuw;
wire divw;
wire mul;
wire mulw;

ysyx_22040213_IDU idu(
	.inst(o_id_inst_sram[31:0]),
	.rs1(rs1),
	.rs2(rs2),
	.rd(rd),
	.funct3(funct3),
	.funct7(funct7),
	.opcode(opcode),
	.shamt(shamt),
	.ext_imm(ext_imm),
	.csr_rs1(csr_rs1),
	.csr_waddr(csr_waddr),
	.mret(mret),
	.ecall(ecall),
	.csrrs(csrrs),
	.rem(rem),
	.remu(remu),
	.remw(remw),
	.remuw(remuw),
	.div(div),
	.divu(divu),
	.divw(divw),
	.divuw(divuw),
	.mul(mul),
	.mulw(mulw),
	.csrrw(csrrw)
);

ysyx_22040213_contrl ctrl1(
	.opcode(opcode),
	.funct3(funct3),
	.funct7(funct7),
	.jumpb(jumpb),
	.csrrw(csrrw),
	.csrrs(csrrs),
	.ecall(ecall||clint_trap_go),
	.mret(mret),
	.csr_wen(csr_wen),
	.w_en(w_en),
	.pc_en(pc_en),
	.jumpb_en(jumpb_en),
	.lm_en(lm_en),
	.sm_en(sm_en),
	.sub_en(sub_en),
	.word_en(word_en),
	.rv64m_en(rv64m_en),
	.arith_en(arith_en),
	.lui_en(lui_en),
	.srai(srai),
	.nextpc_en(nextpc_en),
	.op_jalr(op_jalr),
	.RegisterWritedata_en(RegisterWritedata_en),
	.remw(remw),
	.remuw(remuw),
	.divw(divw),
	.divuw(divuw),
	.AluData1_en(AluData1_en),
	.AluData2_en(AluData2_en)
);



ysyx_22040213_branchif bi1(
	.jumpb_en(jumpb_en),
	.funct3(funct3),
	.data1(o_bub_src1),
	.data2(o_bub_src2),
	.jumpb(jumpb)
);

wire to_fs_valid;

ysyx_22040213_nextpc dnpc1(
	.clk(clk),
	.rst(rst),

	.exe_reg_w_en(o_exe_reg_w_en),
	.IF_allow_in(IF_allow_in),
	//handshake//
	//pre if-ready go//
	.pc_stall(pc_stall),
	.valid_in(valid_in),
//	.inst_addr_ok(o_instram_addr_ok),//SRAM LIKE
//	.inst_addr_ok(o_axi_inst_addr_ok && o_if_req),//AXI
	.inst_addr_ok(o_icache_addr_ok && o_if_req),//cache
//-----------------------//
	.to_fs_valid(to_fs_valid),
	//clint//
	.clint_trap_go(clint_trap_go),
	.o_clint_trap_go(o_clint_trap_go),
	.br_bus_valid(br_bus_valid),
	.pc_ready_go(pc_ready_go),	
	.IF_valid(IF_valid),	
	.nextpc_en(nextpc_en), //pre if addr not ok   if data_ok
//	.jumpb_en(jumpb_en & {IF_valid}),
	.src1(o_bub_src1),
	.ext_imm(ext_imm),
	.pc_add_four(o_id_pc_link),
	.mepc(mepc),
	.mtvec(mtvec),
	.pc(pc),
	.dnpc(dnpc)
);


wire REG_allow_in;
wire valid_out;
wire [63:0] csr_src1;
wire [1:0] csr_wen;
wire [11:0] csr_waddr;
wire [63:0] mepc;
wire [63:0] mtvec;
wire [63:0] clint_rdata;
wire clint_trap_go;

ysyx_22040213_RegisterFile #(32,64) reg1(
	.clk(clk),
	.rst(rst),
	.wdata(o_wb_wdata),
	.waddr(o_wb_rd),
	.w_en(o_wb_w_en),

	.rs1(rs1),
	.rs2(rs2),
	.src1(src1),
	.src2(src2),
	//csr//
	.ecall(ecall),
	.o_if_pc(o_if_pc),
	.csr_wen(csr_wen),
	.i_csr_waddr(csr_waddr),
	.csr_wdata(o_bub_src1),
	.csr_rs1(csr_rs1),
	.csr_src1(csr_src1),
	.mtvec(mtvec),
	.mepc(mepc),
	//clint//
	.clint_wen(clint_wen),
	.clint_ren(clint_ren),
	.clint_addr(clint_addr),
	.clint_wdata(clint_wdata),
	.clint_rdata(clint_rdata),
	.i_if_pc(pc),
	.ID_ready_go(o_bub_ID_ready_go),
	.clint_trap_go(clint_trap_go),

	//hand shake//
	.out_allow(out_allow),
	.WB_to_REG_valid(WB_to_REG_valid),

	.REG_allow_in(REG_allow_in),
	.valid_out(valid_out),
	//for difftest//
	.i_reg_id_bubble(o_wb_id_bubble),
	.i_reg_exe_bubble(o_wb_exe_bubble),
	.i_reg_dnpc(o_wb_dnpc),
	.i_reg_inst(o_wb_inst),
	.i_reg_valid(WB_to_REG_valid),
	.i_reg_devices_access(o_wb_devices_access),

	.o_reg_id_bubble(o_reg_id_bubble),
	.o_reg_exe_bubble(o_reg_exe_bubble),
	.o_reg_dnpc(o_reg_dnpc),
	.o_reg_inst(o_reg_inst),
	.o_reg_valid(o_reg_valid),
	.o_reg_devices_access(o_reg_devices_access)
);

ysyx_22040213_aluop alu_op1( //alu ctrl signal
	.funct3(funct3),
	.sub_en(sub_en),
	.pc_en(pc_en),
	.sm_en(sm_en),
	.lm_en(lm_en),
	.word_en(word_en),
	.rv64m_en(rv64m_en),
	.arith_en(arith_en),
	.lui_en(lui_en),
	.srai(srai),
	.rem(rem),
	.remu(remu),
	.remw(remw),
	.remuw(remuw),
	.div(div),
	.divu(divu),
	.divw(divw),
	.divuw(divuw),
	.mul(mul),
	.mulw(mulw),

	.alu_op(alu_op)
);




//----------END--ID------------//
//----------ID-EXE-REG---------//
//wire EXE_ready_go = dataram_addr_ok;
//wire EXE_ready_go = o_axi_data_addr_ok || !o_data_req;  //if req must addr_ok
wire EXE_ready_go = (o_dcache_addr_ok || !o_data_req) && (!alu_busy);  //if req must addr_ok
wire EXE_allow_in;
wire EXE_to_MEM_valid;

wire [3:0] o_exe_AluData1_en;
wire [6:0] o_exe_AluData2_en;
wire [63:0] o_exe_src1;
wire [63:0] o_exe_src2;
wire [63:0] o_exe_ext_imm;
wire [63:0] o_exe_pc_link;
wire [63:0] o_exe_shamt;
wire [16:0] o_exe_alu_op;
wire [2:0] o_exe_funct3;
wire [4:0] o_exe_rd;
wire o_exe_w_en;
wire o_exe_word_en;
wire o_exe_sm_en;
wire o_exe_lm_en;
wire [3:0] o_exe_RegWrite_en;
wire [63:0] o_exe_csr_src1;
wire o_exe_reg_w_en;

// for difftest //
wire [31:0] o_exe_inst;
wire [63:0] o_exe_dnpc;
wire o_exe_id_bubble;
wire o_exe_exe_bubble;
wire o_exe_clint_trap;

ysyx_22040213_EXEReg buf2_ID_EXE_REG(
	.clk(clk),
	.rst(rst),
	.flush(exe_flush),

	.ID_to_EXE_valid(ID_to_EXE_valid),
	.EXE_ready_go(EXE_ready_go),
	.MEM_allow_in(MEM_allow_in),

	.EXE_to_MEM_valid(EXE_to_MEM_valid),
	.EXE_allow_in(EXE_allow_in),

	.i_exe_AluData1_en(AluData1_en),
	.i_exe_AluData2_en(AluData2_en),
	.i_exe_src1(o_bub_src1),              
	.i_exe_src2(o_bub_src2),
	.i_exe_ext_imm(ext_imm),          
	.i_exe_pc_link(o_id_pc_link),        
	.i_exe_shamt(shamt),
	.i_exe_alu_op(alu_op),
	.i_exe_funct3(funct3),
	.i_exe_rd(rd),
	.i_exe_w_en(w_en),
	.i_exe_word_en(word_en),
 	.i_exe_lm_en(lm_en),
	.i_exe_sm_en(sm_en),
	.i_exe_RegWrite_en(RegisterWritedata_en),
	.i_exe_csr_src1(csr_src1),

	.o_exe_AluData1_en(o_exe_AluData1_en),
	.o_exe_AluData2_en(o_exe_AluData2_en),
	.o_exe_src1(o_exe_src1),              
	.o_exe_src2(o_exe_src2),
	.o_exe_ext_imm(o_exe_ext_imm),          
	.o_exe_pc_link(o_exe_pc_link),        
	.o_exe_shamt(o_exe_shamt),
	.o_exe_alu_op(o_exe_alu_op),
	.o_exe_funct3(o_exe_funct3),
	.o_exe_rd(o_exe_rd),
	.o_exe_w_en(o_exe_w_en),
	.o_exe_word_en(o_exe_word_en),
	.o_exe_lm_en(o_exe_lm_en),
	.o_exe_sm_en(o_exe_sm_en),
	.o_exe_RegWrite_en(o_exe_RegWrite_en),
	.o_exe_csr_src1(o_exe_csr_src1),
	.o_exe_reg_w_en(o_exe_reg_w_en),
	//for difftest//
	.i_exe_id_bubble(id_bubble),
	.i_exe_exe_bubble(exe_bubble),
	.i_exe_dnpc(o_if_dnpc),
	.i_exe_inst(o_id_inst_sram[31:0]),
	.i_exe_clint_trap(o_id_diff_clint_trap),

	.o_exe_id_bubble(o_exe_id_bubble),
	.o_exe_exe_bubble(o_exe_exe_bubble),
	.o_exe_dnpc(o_exe_dnpc),
	.o_exe_inst(o_exe_inst),
	.o_exe_clint_trap(o_exe_clint_trap)

);

//--------------EXE------------//

wire [63:0] adata;
wire [63:0] adatain;
wire [63:0] data1;
wire [63:0] data2;
wire alu_busy;

ysyx_22040213_inDataSel insel1(
	.AluData1_en(o_exe_AluData1_en), //from ID
	.AluData2_en(o_exe_AluData2_en), //from ID
	.src1(o_exe_src1),              //from ID
	.src2(o_exe_src2),
	.ext_imm(o_exe_ext_imm),          //from ID
	.pc(o_exe_pc_link),                    //from IF
	.shamt(o_exe_shamt),
	.data1(data1),
	.data2(data2)

);



ysyx_22040213_ALU alu1(
	.data1(data1),
	.data2(data2),
	.alu_op(o_exe_alu_op),
	.clk(clk),
	.rst(rst),
	.MEM_allow_in(MEM_allow_in),
	.alu_busy(alu_busy),
	.wdata(adatain)
);

ysyx_22040213_aluout alu_out(
	.word_en(o_exe_word_en),
	.adata(adatain),
	.adataout(adata)
);


//----------END-EXE------------//
//---------EXE-MEM-REG--------//
//wire MEM_ready_go = dataram_data_ok;
//wire MEM_ready_go = o_axi_data_data_ok || !mem_req;
wire MEM_ready_go = o_dcache_data_ok || !mem_req;
wire MEM_allow_in;
wire MEM_to_WB_valid;


wire [63:0] o_mem_src2;
wire [63:0] o_mem_adata;
wire [2:0] o_mem_funct3;
wire o_mem_sm_en;
wire o_mem_lm_en;
wire [4:0] o_mem_rd;
wire o_mem_w_en;
wire [63:0] o_mem_pc_link;
wire [3:0] o_mem_RegWrite_en;
wire [63:0] o_mem_csr_src1;
wire o_mem_clint_hit;
//for difftest//
wire o_mem_id_bubble;
wire o_mem_exe_bubble;
wire [31:0] o_mem_inst;
wire [63:0] o_mem_dnpc;
wire o_mem_devices_access;

ysyx_22040213_MEMReg buf3_EXE_MEM_REG(
	.clk(clk),
	.rst(rst),

	.EXE_to_MEM_valid(EXE_to_MEM_valid),
	.MEM_ready_go(MEM_ready_go),
	.WB_allow_in(WB_allow_in),

	.MEM_to_WB_valid(MEM_to_WB_valid),
	.MEM_allow_in(MEM_allow_in),

	.i_mem_src2(o_exe_src2), //from ID
	.i_mem_adata(adata), //from EXE
	.i_mem_funct3(o_exe_funct3), //from ID
	.i_mem_sm_en(o_exe_sm_en),  //from iD
	.i_mem_lm_en(o_exe_lm_en),   //from id
	.i_mem_rd(o_exe_rd),
	.i_mem_w_en(o_exe_w_en),
	.i_mem_pc_link(o_exe_pc_link),
	.i_mem_RegWrite_en(o_exe_RegWrite_en),
	.i_mem_csr_src1(o_exe_csr_src1),
	.i_mem_clint_hit(clint_hit),

	.o_mem_src2(o_mem_src2),
	.o_mem_adata(o_mem_adata),
	.o_mem_funct3(o_mem_funct3),
	.o_mem_sm_en(o_mem_sm_en),
	.o_mem_lm_en(o_mem_lm_en),
	.o_mem_rd(o_mem_rd),
	.o_mem_w_en(o_mem_w_en),
	.o_mem_pc_link(o_mem_pc_link),
	.o_mem_RegWrite_en(o_mem_RegWrite_en),
	.o_mem_csr_src1(o_mem_csr_src1),
	.o_mem_clint_hit(o_mem_clint_hit),

	//for difftest//
	.i_mem_id_bubble(o_exe_id_bubble),
	.i_mem_exe_bubble(o_exe_exe_bubble),
	.i_mem_dnpc(o_exe_dnpc),
	.i_mem_inst(o_exe_inst),
	.i_mem_devices_access(devices_access || clint_hit || o_exe_clint_trap), //from EXE 
	
	.o_mem_id_bubble(o_mem_id_bubble),
	.o_mem_exe_bubble(o_mem_exe_bubble),
	.o_mem_dnpc(o_mem_dnpc),
	.o_mem_inst(o_mem_inst),
	.o_mem_devices_access(o_mem_devices_access)

);

//--------------MEM------------//

wire [63:0] mwdata;
wire [63:0] maddr;
wire [7:0] wmask;
wire [63:0] mrdata;
wire [63:0] wdata;

wire [63:0] mrdata_syn;

wire mem_mem_req = (o_mem_sm_en || o_mem_lm_en) && EXE_to_MEM_valid;
/*
ysyx_22040213_memory mem1(
	.mwdata(o_mem_src2),
	.maddr(o_mem_adata), //from EXE
	.funct3(o_mem_funct3), //from ID
	.mrdata(mrdata), //to WB
	.sm_en(o_mem_sm_en),  //from iD
	.lm_en(o_mem_lm_en)   //from id
);
*/
wire dataram_data_ok;
wire dataram_addr_ok;
/*
ysyx_22040213_memory_syn mem2(
	.clk(clk),
	.rst(rst),
	.EXE_to_MEM_valid(EXE_to_MEM_valid),
//	.mwdata(o_exe_src2),
	.maddr(adata), 
	.funct3(o_exe_funct3), 
	.mrdata(mrdata_syn),
	.sm_en(o_exe_sm_en),  
	.lm_en(o_exe_lm_en),
        .data_ok(dataram_data_ok),	
	.addr_ok(dataram_addr_ok)
);
*/
wire [63:0] mrdata_axi;
wire data_addr_ok;
wire data_data_ok;
wire o_data_wr;
wire o_data_req;
wire [2:0] o_data_size;
wire [63:0] o_data_addr;
wire [7:0] o_data_wstrb;
wire [63:0] o_data_wdata;
wire [63:0] i_data_rdata;
wire mem_req = (o_mem_sm_en || o_mem_lm_en) && !o_mem_clint_hit;
//clint//
wire clint_hit;
wire clint_wen;
wire clint_ren;
wire clint_addr;
wire [63:0] clint_wdata;

ysyx_22040213_memory_port mem3(
	.rst(rst),
//	.EXE_to_MEM_valid(EXE_to_MEM_valid),
	.mwdata(o_exe_src2),
	.maddr(adata), 
	.exe_funct3(o_exe_funct3),
	.mem_funct3(o_mem_funct3), 
	.o_data_mrdata(mrdata_axi),
	.sm_en(o_exe_sm_en),  
	.lm_en(o_exe_lm_en),
	//clint
	.clint_wen(clint_wen),
	.clint_ren(clint_ren),
	.clint_addr(clint_addr),
	.clint_wdata(clint_wdata),
	.clint_hit(clint_hit),

	.data_addr_ok(data_addr_ok),
	.data_data_ok(data_data_ok),

	.i_data_addr_ok(i_data_addr_ok),
	.i_data_data_ok(i_data_data_ok),
	.i_data_rdata(o_dcache_rdata),
	
	.o_data_wr(o_data_wr),
	.o_data_req(o_data_req),
	.o_data_size(o_data_size),
	.o_data_addr(o_data_addr),
	.o_data_wstrb(o_data_wstrb),
	.o_data_wdata(o_data_wdata)
);

wire i_data_addr_ok;
wire i_data_data_ok;

wire o_dcache_addr_ok;
wire o_dcache_data_ok;
wire [63:0] o_dcache_rdata;

wire o_dcache_rd_req;
wire [2:0] o_dcache_rd_type;
wire [63:0] o_dcache_rd_addr;
wire o_dcache_wr_req;
wire [2:0] o_dcache_wr_type;
wire [63:0] o_dcache_wr_addr;
wire [7:0] o_dcache_wr_wstrb;
wire [63:0] o_dcache_wr_data;
wire devices_access;

ysyx_22040213_cache dcache(
	.clk(clk),
	.rst(rst),
	
	.i_cache_req(o_data_req),
	.i_cache_wr(o_data_wr),
	.i_cache_addr(o_data_addr),
	.i_cache_wdata(o_data_wdata),
	.i_cache_wstrb(o_data_wstrb),
	.o_cache_addr_ok(o_dcache_addr_ok),
	.o_cache_data_ok(o_dcache_data_ok),
	.o_cache_rdata(o_dcache_rdata),

	.o_cache_rd_req(o_dcache_rd_req),
	.o_cache_rd_type(o_dcache_rd_type),
	.o_cache_rd_addr(o_dcache_rd_addr),
	.i_cache_rd_rdy(i_dcache_rd_rdy),

	.i_cache_ret_valid(i_dcache_ret_valid),
	.i_cache_ret_last(i_dcache_ret_last),
	.i_cache_ret_data(i_dcache_ret_data),

	.o_cache_wr_req(o_dcache_wr_req),
	.o_cache_wr_type(o_dcache_wr_type),
	.o_cache_wr_addr(o_dcache_wr_addr),
	.o_cache_wr_wstrb(o_dcache_wr_wstrb),
	.o_cache_wr_data(o_dcache_wr_data),
	.i_cache_wr_rdy(i_dcache_wr_rdy),
	.devices_access(devices_access)
);

/*
ysyx_22040213_dataram dram(
	.clk(clk),
	.rst(rst),
	.dataram_req(o_data_req),
	.wr(o_data_wr),
	.size(o_data_size),
	.addr(o_data_addr),
	.wstrb(o_data_wstrb),
	.wdata(o_data_wdata),

	.addr_ok(i_data_addr_ok),
	.data_ok(i_data_data_ok),
	.rdata(i_data_rdata)
);
*/
  //----------inst sram like-------------//
  wire o_axi_inst_addr_ok;
  wire o_axi_inst_data_ok;
  wire [63:0] o_axi_inst_rdata;
  //-----------data sram like-----------//
  wire o_axi_data_addr_ok;
  wire o_axi_data_data_ok;
  wire [63:0] o_axi_data_rdata;
  //-----------AXI----------------------//
  //-----------ar-----------------------//
  wire i_axi_master_arready;
  wire o_axi_master_arvalid;

  wire [63:0] o_axi_master_araddr;
  wire [3:0]  o_axi_master_arid;
  wire [7:0]  o_axi_master_arlen;
  wire [2:0]  o_axi_master_arsize;
  wire [1:0]  o_axi_master_arburst;
  
  //------------r-----------------------//
  wire o_axi_master_rready;

  wire i_axi_master_rvalid;
  wire i_axi_master_rlast;
  wire [1:0]  i_axi_master_rresp;
  wire [63:0] i_axi_master_rdata;
  wire [3:0]  i_axi_master_rid;
  
  //------------aw-----------------------//
  wire i_axi_master_awready;

  wire o_axi_master_awvalid;
  wire [63:0] o_axi_master_awaddr;
  wire [3:0]  o_axi_master_awid;
  wire [7:0]  o_axi_master_awlen;
  wire [2:0]  o_axi_master_awsize;
  wire [1:0]  o_axi_master_awburst;

  //-------------w-----------------------//
  wire i_axi_master_wready;

  wire o_axi_master_wvalid;
  wire [63:0] o_axi_master_wdata;
  wire [7:0]  o_axi_master_wstrb;
  wire  o_axi_master_wlast;

  //-------------b-----------------------//
  wire o_axi_master_bready;

  wire i_axi_master_bvalid;
  wire [1:0] i_axi_master_bresp;
  wire [3:0] i_axi_master_bid;
  // icache//
  wire i_icache_rd_rdy;
  wire i_icache_ret_valid;
  wire i_icache_ret_last;
  wire [63:0] i_icache_ret_data;
  wire i_icache_wr_rdy;
  // dcache//
  wire i_dcache_rd_rdy;
  wire i_dcache_ret_valid;
  wire i_dcache_ret_last;
  wire [63:0] i_dcache_ret_data;
  wire i_dcache_wr_rdy;


ysyx_22040213_axi_interface axi1(
 .clk(clk),
 .rst(rst),
 //-------------icache-----------------//
 .i_axi_icache_rd_req(o_icache_rd_req),
// .i_axi_icache_rd_type(o_icache_rd_type),
 .i_axi_icache_rd_addr(o_icache_rd_addr),
 .o_axi_icache_rd_rdy(i_icache_rd_rdy),

 .o_axi_icache_ret_valid(i_icache_ret_valid),
 .o_axi_icache_ret_last(i_icache_ret_last),
 .o_axi_icache_ret_data(i_icache_ret_data),

// .i_axi_icache_wr_req(o_icache_wr_req),	
// .i_axi_icache_wr_type(o_icache_wr_type),
// .i_axi_icache_wr_addr(o_icache_wr_addr),
// .i_axi_icache_wr_wstrb(o_icache_wr_wstrb),
// .i_axi_icache_wr_data(o_icache_wr_data),
 .o_axi_icache_wr_rdy(i_icache_wr_rdy),
 
 //-------------dcache-----------------//
 .i_axi_dcache_rd_req(o_dcache_rd_req),
// .i_axi_dcache_rd_type(o_dcache_rd_type),
 .i_axi_dcache_rd_addr(o_dcache_rd_addr),
 .o_axi_dcache_rd_rdy(i_dcache_rd_rdy),

 .o_axi_dcache_ret_valid(i_dcache_ret_valid),
 .o_axi_dcache_ret_last(i_dcache_ret_last),
 .o_axi_dcache_ret_data(i_dcache_ret_data),

 .i_axi_dcache_wr_req(o_dcache_wr_req),	
// .i_axi_dcache_wr_type(o_dcache_wr_type),
 .i_axi_dcache_wr_addr(o_dcache_wr_addr),
 .i_axi_dcache_wr_wstrb(o_dcache_wr_wstrb),
 .i_axi_dcache_wr_data(o_dcache_wr_data),
 .o_axi_dcache_wr_rdy(i_dcache_wr_rdy),
//------------sram-like---------------//
// .i_axi_inst_req(o_icache_rd_req),
// .i_axi_inst_req(o_icache_req),
// .i_axi_inst_addr(o_icache_rd_addr),
// .i_axi_inst_addr(o_icache_addr), 
// .o_axi_inst_addr_ok(o_axi_inst_addr_ok),
// .o_axi_inst_data_ok(o_axi_inst_data_ok),
// .o_axi_inst_rdata(o_axi_inst_rdata),
/*
 .i_axi_data_wr(o_data_wr),
 .i_axi_data_req(o_data_req),
// .i_axi_data_size(o_data_size),
 .i_axi_data_addr(o_data_addr),
 .i_axi_data_wstrb(o_data_wstrb),
 .i_axi_data_wdata(o_data_wdata),
 .o_axi_data_addr_ok(o_axi_data_addr_ok),
 .o_axi_data_data_ok(o_axi_data_data_ok),
 .o_axi_data_rdata(o_axi_data_rdata),*/
  //-----------AXI----------------------//
  //-----------ar-----------------------//
 .i_axi_master_arready(i_axi_master_arready),
 .o_axi_master_arvalid(o_axi_master_arvalid),
 .o_axi_master_araddr(o_axi_master_araddr),
 .o_axi_master_arid(o_axi_master_arid),
 .o_axi_master_arlen(o_axi_master_arlen),
 .o_axi_master_arsize(o_axi_master_arsize),
 .o_axi_master_arburst(o_axi_master_arburst),
  //------------r-----------------------//
 .o_axi_master_rready(o_axi_master_rready),
 .i_axi_master_rvalid(i_axi_master_rvalid),
// .i_axi_master_rlast(i_axi_master_rlast),
// .i_axi_master_rresp(i_axi_master_rresp),
 .i_axi_master_rdata(i_axi_master_rdata),
 .i_axi_master_rid(i_axi_master_rid),
  //------------aw-----------------------//
 .i_axi_master_awready(i_axi_master_awready),
 .o_axi_master_awvalid(o_axi_master_awvalid),
 .o_axi_master_awaddr(o_axi_master_awaddr),
 .o_axi_master_awid(o_axi_master_awid),
 .o_axi_master_awlen(o_axi_master_awlen),
 .o_axi_master_awsize(o_axi_master_awsize),
 .o_axi_master_awburst(o_axi_master_awburst),
  //-------------w-----------------------//
 .i_axi_master_wready(i_axi_master_wready),
 .o_axi_master_wvalid(o_axi_master_wvalid),
 .o_axi_master_wdata(o_axi_master_wdata),
 .o_axi_master_wstrb(o_axi_master_wstrb),
 .o_axi_master_wlast(o_axi_master_wlast),
  //-------------b-----------------------//
 .o_axi_master_bready(o_axi_master_bready),
 .i_axi_master_bvalid(i_axi_master_bvalid)
// .i_axi_master_bresp(i_axi_master_bresp),
// .i_axi_master_bid(i_axi_master_bid)
);

ysyx_22040213_ram_axi ram1(
 .clk(clk),
 .rst(rst),
 //-----------ar-----------------------//
 .o_axi_slave_arready(i_axi_master_arready),
 .i_axi_slave_arvalid(o_axi_master_arvalid),
 .i_axi_slave_araddr(o_axi_master_araddr),
// .i_axi_slave_arid(o_axi_master_arid),
// .i_axi_slave_arlen(o_axi_master_arlen),
// .i_axi_slave_arsize(o_axi_master_arsize),
// .i_axi_slave_arburst(o_axi_master_arburst),
  //------------r-----------------------//
 .i_axi_slave_rready(o_axi_master_rready),
 .o_axi_slave_rvalid(i_axi_master_rvalid),
// .o_axi_slave_rlast(o_axi_slave_rlast),
// .o_axi_slave_rresp(o_axi_slave_rresp),
 .o_axi_slave_rdata(i_axi_master_rdata),
// .o_axi_slave_rid(o_axi_slave_rid),
  //------------aw-----------------------//
 .o_axi_slave_awready(i_axi_master_awready),
 .i_axi_slave_awvalid(o_axi_master_awvalid),
 .i_axi_slave_awaddr(o_axi_master_awaddr),
// .i_axi_slave_awid(o_axi_master_awid),
// .i_axi_slave_awlen(o_axi_master_awlen),
// .i_axi_slave_awsize(o_axi_master_awsize),
// .i_axi_slave_awburst(o_axi_master_awburst),
  //-------------w-----------------------//
 .o_axi_slave_wready(i_axi_master_wready),
 .i_axi_slave_wvalid(o_axi_master_wvalid),
 .i_axi_slave_wdata(o_axi_master_wdata),
 .i_axi_slave_wstrb(o_axi_master_wstrb),
// .i_axi_slave_wlast(o_axi_master_wlast),
  //-------------b-----------------------//
 .i_axi_slave_bready(o_axi_master_bready),
 .o_axi_slave_bvalid(i_axi_master_bvalid)
// .o_axi_slave_bresp(o_axi_slave_bresp),
// .o_axi_slave_bid(i_axi_master_bid)
); 
wire need = (o_data_addr == 64'h800002b0) & o_data_wr;
inst_compare com2(
	.instt(mrdata_syn & {64{RegisterWritedata_en[2] & o_dcache_data_ok}}),
	.instt_syn(mrdata_axi & {64{RegisterWritedata_en[2] & o_dcache_data_ok}})
);

ysyx_22040213_outDataSel sel2(
	.csr_src1(o_mem_csr_src1),
	.mrdata(mrdata_axi),
	.adata(o_mem_adata),
	.pc_link(o_mem_pc_link),
	.clint_hit(o_mem_clint_hit),
	.clint_rdata(clint_rdata),

	.wdata(wdata),

	.RegisterWritedata_en(o_mem_RegWrite_en)
);

//-----------END-MEM-----------//
//-----------WBREG-----------//
wire WB_ready_go = 1'b1;
wire WB_allow_in;
wire WB_to_REG_valid;

wire [4:0] o_wb_rd;
wire o_wb_w_en;
wire [63:0] o_wb_wdata;
//for difftest//
wire o_wb_id_bubble;
wire o_wb_exe_bubble;
wire o_wb_devices_access;
wire [31:0] o_wb_inst;
wire [63:0] o_wb_dnpc;


ysyx_22040213_WBReg buf4_MEM_WB_REG(
	.clk(clk),
	.rst(rst),

	.MEM_to_WB_valid(MEM_to_WB_valid),
	.WB_ready_go(WB_ready_go),
	.REG_allow_in(REG_allow_in),

	.WB_allow_in(WB_allow_in),
	.WB_to_REG_valid(WB_to_REG_valid),

	.i_wb_rd(o_mem_rd),
	.i_wb_w_en(o_mem_w_en),
	.i_wb_wdata(wdata),

	.o_wb_rd(o_wb_rd),
	.o_wb_w_en(o_wb_w_en),
	.o_wb_wdata(o_wb_wdata),

	//for difftest//
	.i_wb_id_bubble(o_mem_id_bubble),
	.i_wb_exe_bubble(o_mem_exe_bubble),
	.i_wb_dnpc(o_mem_dnpc),
	.i_wb_inst(o_mem_inst),
	.i_wb_devices_access(o_mem_devices_access),
		
	.o_wb_id_bubble(o_wb_id_bubble),
	.o_wb_exe_bubble(o_wb_exe_bubble),
	.o_wb_dnpc(o_wb_dnpc),
	.o_wb_inst(o_wb_inst),
	.o_wb_devices_access(o_wb_devices_access)


);

//----------------WB-----------//
wire out_allow = 1'b1;

//----------END-WB------------//


endmodule
